package com.ecoolex.ying.space.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.exception.BizException;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.pojo.Sortings;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.ying.space.core.dao.UserLikeRecordDAO;
import com.ecoolex.ying.space.entity.UserLikeAndFavoriteReadState;
import com.ecoolex.ying.space.entity.UserLikeRecord;
import com.ecoolex.ying.space.entity.UserLikeRecord.Column;
import com.ecoolex.ying.space.entity.UserLikeRecordExample;
import com.ecoolex.ying.space.entity.UserLikeRecordExample.Criteria;
import com.ecoolex.ying.space.entity.UserWorks;
import com.ecoolex.ying.space.entity.UserWorksComment;
import com.ecoolex.ying.space.enums.UserLikeRecordType;
import com.ecoolex.ying.space.pojo.UserLikeAndFavoriteDTO;

import java.time.Instant;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserLikeRecordManager {

    @Autowired
    private UserLikeRecordDAO dao;

    @Autowired
    private UserWorksManager userWorksManager;

    @Autowired
    private UserWorksCommentManager userWorksCommentManager;

    @Autowired
    private ProducerService producerService;

    @Autowired
    private UserLikeAndFavoriteReadStateManager userLikeAndFavoriteReadStateManager;


    /**
     * 点赞
     *
     * @param record
     * @param createUser
     * @return
     */
    @Transactional
    public boolean add(UserLikeRecord record, Integer userId, String createUser) {
        BizAssert.isTrue(Check.notNull(record.getType()), ResultCode.VERIFY.build(10), "点赞类型为空");
        BizAssert.isTrue(Check.notNullAndGtZero(record.getContentId()), ResultCode.VERIFY.build(11), "内容id为空");
        //用户重复点赞，直接返回
        UserLikeRecord old = getByUserIdAndTypeAndContentId(userId, record.getType(), record.getContentId());
        if (Check.notNull(old)) {
            return true;
        }
        if (UserLikeRecordType.USERWORKS.real().equals(record.getType())) {
            UserWorks userWorks = userWorksManager.getById(record.getContentId());
            BizAssert.isTrue(Check.notNull(userWorks), ResultCode.VERIFY.build(12), "作品不存在");
            record.setContentAuthorUserId(userWorks.getUserId());
            //点赞作品统计消息
            producerService.sendUserLikeUserWorksCreate(record.getContentId());
        } else if (UserLikeRecordType.COMMENT.real().equals(record.getType())) {
            UserWorksComment userWorksComment = userWorksCommentManager.getById(record.getContentId());
            BizAssert.isTrue(Check.notNull(userWorksComment), ResultCode.VERIFY.build(13), "评论不存在");
            record.setContentAuthorUserId(userWorksComment.getCommentUserId());
            //点赞评论统计消息
            producerService.sendUserLikeUserWorksCommentCreate(record.getContentId());
        } else {
            throw BizException.create(ResultCode.VERIFY.build(14), "点赞类型无效");
        }
        record.setUserId(userId);
        record.setDeleted(UserLikeRecord.NOT_DELETED);
        record.setCreateUser(createUser);
        record.setCreateTime(Date.from(Instant.now()));
        record.setUpdateUser(createUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.insert(record);

        return true;
    }

    /**
     * 取消点赞
     *
     * @param record
     * @param updateUser
     */
    public boolean delete(UserLikeRecord record, String updateUser) {
        record.setDeleted(UserLikeRecord.IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record, Column.deleted, Column.updateUser, Column.updateTime);
        if (UserLikeRecordType.USERWORKS.real().equals(record.getType())) {
            //取消点赞作品统计消息
            producerService.sendUserLikeUserWorksCancel(record.getContentId());
        }
        if (UserLikeRecordType.COMMENT.real().equals(record.getType())) {
            //取消点赞评论统计消息
            producerService.sendUserLikeUserWorksCommentCancel(record.getContentId());
        }
        return true;
    }

    public UserLikeRecord getByUserIdAndTypeAndContentId(Integer userId, Integer type, Integer contentId) {
        UserLikeRecordExample example = new UserLikeRecordExample();
        Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId).andTypeEqualTo(type).andContentIdEqualTo(contentId).andDeletedEqualTo(UserLikeRecord.NOT_DELETED);
        return dao.selectOneByExample(example);
    }

    /**
     * 我发出的点赞
     *
     * @param userId
     * @param sorts
     * @param page
     * @return
     */
    public Pagination<UserLikeRecord> queryByUserId(Integer userId, Sorting[] sorts, Page page) {
        UserLikeRecordExample example = new UserLikeRecordExample();
        Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId).andDeletedEqualTo(UserLikeRecord.NOT_DELETED);
        example.setOffset(page.getFirstIndex());
        example.setRows(page.getPageSize());
        example.orderBy(Sortings.builder(sorts).verify(Column::valueOf).toSql());
        return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExample(example));
    }

    /**
     * 我收到的点赞和收藏
     *
     * @param contentAuthorUserId
     * @param sorts
     * @param page
     * @return
     */
    public Pagination<UserLikeAndFavoriteDTO> queryByContentAuthorUserId(Integer contentAuthorUserId, Date now, Sorting[] sorts, Page page) {
        return Pagination.create(page,
                dao.countByContentAuthorUserId(contentAuthorUserId, now),
                () -> dao.queryByContentAuthorUserId(contentAuthorUserId, now, Sortings.builder(sorts).verify(Column::valueOf).toSql(), page));
    }


    public long unreadReceivedUserLikeAndFavoriteCount(Integer userId) {
        UserLikeAndFavoriteReadState readState = userLikeAndFavoriteReadStateManager.get(userId);
        if (Check.notNull(readState)) {
            return dao.countByContentAuthorUserIdAndReadTime(userId, Date.from(Instant.now()), readState.getNewReadTime());
        }
        return dao.countByContentAuthorUserId(userId, Date.from(Instant.now()));
    }

    public Integer userLikeCountByContentAuthorUserId(Integer userId) {
        UserLikeRecordExample example = new UserLikeRecordExample();
        Criteria criteria = example.createCriteria();
        criteria.andContentAuthorUserIdEqualTo(userId).andDeletedEqualTo(UserLikeRecord.NOT_DELETED);
        List<UserLikeRecord> list = dao.selectByExample(example);
        return list.size();
    }

}